/*
 * Copyright 2012 Adrian Sulumberchean

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
 */

package ro.sands.requests.android.tools;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.UUID;

import ro.sands.requests.android.MyApplication;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.telephony.TelephonyManager;
import android.util.Log;

/**
 * @author Adrian Sulumberchean
 *
 */
public class Util {

	private static float scale = MyApplication.getContext().getResources().getDisplayMetrics().density;
	private static String LOG_TAG = "HttpRequest";
	
	public static int getDPinPX(int size){
		int realSize = (int) (size * scale);

		if(size % scale != 0){
			realSize++;
		}

		return realSize;
	}

	private static int partition(ArrayList<Long> arr, int start, int end) { 
		int i = start, j = end; 
		Long tmp; 
		long pivot = arr.get((start + end) / 2); 

		while (i <= j) { 
			while (arr.get(i) < pivot) 
				i++; 
			while (arr.get(j) > pivot) 
				j--; 
			if (i <= j) { 
				tmp = arr.get(i); 
				arr.set(i, arr.get(j)); 
				arr.set(j, tmp); 
				i++; 
				j--; 
			} 
		}; 	     
		return i; 
	} 

	public static void quickSort(ArrayList<Long> arr, int start, int end) { 
		int index = partition(arr, start, end); 
		if (start < index - 1) 
			quickSort(arr, start, index - 1); 
		if (index < end) 
			quickSort(arr, index, end); 
	}

	public static String getLocalIpAddress() {
		try {
			for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
				NetworkInterface intf = en.nextElement();
				for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
					InetAddress inetAddress = enumIpAddr.nextElement();
					if (!inetAddress.isLoopbackAddress()) {
						return inetAddress.getHostAddress().toString();
					}
				}
			}
		} catch (SocketException ex) {
			ex.printStackTrace();
		}
		return "";
	}

	/**
	 * 
	 * @return true if network connection exists, false if not
	 */
	public static boolean isNetworkConnected() {
		ConnectivityManager cm = (ConnectivityManager)MyApplication.getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
		NetworkInfo netInfo = cm.getActiveNetworkInfo();

		return (netInfo != null && netInfo.isConnected());
	}

	public static String getDeviceId(){
		final TelephonyManager tm = (TelephonyManager) MyApplication.getContext().getSystemService(Context.TELEPHONY_SERVICE);

		final String tmDevice, tmSerial, androidId;
		tmDevice = "" + tm.getDeviceId();
		tmSerial = "" + tm.getSimSerialNumber();
		androidId = "" + android.provider.Settings.Secure.getString(MyApplication.getContext().getContentResolver(), android.provider.Settings.Secure.ANDROID_ID);

		UUID deviceUuid = new UUID(androidId.hashCode(), ((long)tmDevice.hashCode() << 32) | tmSerial.hashCode());
		return deviceUuid.toString();
	}

	public static String concatStrings(String[] strings){
		return concatStrings(strings, ";");
	}

	public static String concatStrings(String[] strings, String delimiter){
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < strings.length; i++) {
			String string = strings[i];
			if (string != null && !"".equals(string)){
				sb.append(string);
				sb.append(delimiter);		
			}
		}

		if(sb.length() > 0)
			sb.deleteCharAt(sb.length()-1);

		return sb.toString();
	}

	public static String readFastFromFile(File file) throws Exception{

		FileInputStream f = new FileInputStream(file);

		return readFastFromFile(f);
	}

	public static String readFastFromFile(FileInputStream inputStream) throws Exception{
		StringBuilder builder = new StringBuilder();
		FileChannel ch = inputStream.getChannel( );
		byte[] barray = new byte[inputStream.available()];
		ByteBuffer bb = ByteBuffer.wrap( barray );

		while ( ch.read( bb ) != -1 ) {
			builder.append(new String(barray));

			bb.clear( );
		}

		return builder.toString();
	}

	public static File copyFile(ArrayList<File> fromFile, String toFile){
		File resultFile = new File(toFile);

		try {
			FileOutputStream fos = new FileOutputStream(resultFile);
			for (File file : fromFile) {

				FileInputStream fis = new FileInputStream(file);

				FileChannel ch = fis.getChannel( );
				byte[] barray = new byte[fis.available()];
				ByteBuffer bb = ByteBuffer.wrap( barray );

				while ( ch.read( bb ) != -1 ) {
					fos.write(barray);

					bb.clear( );
				}

				fos.flush();
				fos.close();
				fis.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		return resultFile;
	}

	public static void log(String message){
		log(message, null);
	}
	
	public static void log(String message, Throwable e){
		
		if(e != null){
			Log.d(LOG_TAG, message, e);
			return;
		}
		
		Log.d(LOG_TAG, message);
	}
	
	public static int calculateInSampleSize(
			BitmapFactory.Options options, int reqWidth, int reqHeight) {
		// Raw height and width of image
		final int height = options.outHeight;
		final int width = options.outWidth;
		int inSampleSize = 1;

		if (height > reqHeight || width > reqWidth) {
			if (width > height) {
				inSampleSize = Math.round((float)height / (float)reqHeight);
			} else {
				inSampleSize = Math.round((float)width / (float)reqWidth);
			}
		}
		return inSampleSize;
	}

	public static Bitmap decodeSampledBitmapFromResource(String url,
			int reqWidth, int reqHeight) throws MalformedURLException, IOException {

		// First decode with inJustDecodeBounds=true to check dimensions
		final BitmapFactory.Options options = new BitmapFactory.Options();
		options.inJustDecodeBounds = true;
		BitmapFactory.decodeStream(new URL(url).openStream(), null, options);

		// Calculate inSampleSize
		options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

		// Decode bitmap with inSampleSize set
		options.inJustDecodeBounds = false;
		return Bitmap.createScaledBitmap(BitmapFactory.decodeStream(new URL(url).openStream(), null, options), reqWidth, reqHeight, true);
	}
}
